/*
  封装axios成新的函数
  让外面使用axios更加简单、方便

  1. 定义公共地址前缀
  2. 请求拦截器中可以设置公共请求参数(将来真正完成)
  3. 响应拦截器中返回真正的数据
    之前：获取数据 res.data.data
    希望：获取数据 data
  4. 外面await成功，就是成功
    try catch失败，就是失败
    （成功就是功能成功，失败就是请求失败或功能失败）
  5. 进度条提示
*/

import axios from "axios";
import NProgress from "nprogress";
import "nprogress/nprogress.css";

// 简单理解：创建axios的实例（创建一个新的对象，新对象和axios功能基本一致）
const request = axios.create({
  // 公共地址前缀
  // 将来使用request发送请求，所有请求地址前面都会加上 /api
  baseURL: "/mock",
});

/*
  当你使用request发送请求，触发流程
    1. 触发请求拦截器的回调
    2. 发送请求
    3. 触发响应拦截器的回调
    4. 触发外面调用api函数 async await

    [
      请求拦截器成功回调, 请求拦截器失败回调, 
      发送请求的函数, undefined, 
      响应拦截器成功回调, 响应拦截器失败回调,
    ]

    源码在 axios/lib/Axios.js 中

    let promise = Promise.resolve(config) 
    promise = promise.then(请求拦截器成功回调, 请求拦截器失败回调)
    promise = promise.then(发送请求的函数, undefined)
    promise = promise.then(响应拦截器成功回调, 响应拦截器失败回调)
    最后，触发外面调用api函数 async await
*/

// 请求拦截器：发送请求之前触发
request.interceptors.request.use(
  // 成功
  (config) => {
    // config 请求配置对象
    // 添加公共的请求参数
    // config.headers.token = "xxxxx";

    NProgress.start();

    return config;
  }
  // 失败
  // () => {}
);

// 响应拦截器：响应回来之后触发
request.interceptors.response.use(
  // 成功
  (response) => {
    NProgress.done();

    if (response.data.code === 200) {
      // 功能成功
      return response.data.data;
    }
    // 功能失败
    return Promise.reject(response.data.message || "未知错误");
  },
  // 失败
  (error) => {
    NProgress.done();
    // 请求失败
    return Promise.reject(error);
  }
);

// 暴露出去
export default request;
